package com.example.csmallpassport.web;


import com.example.csmallpassport.ex.ServiceException;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * getter,Setter @Data
 * 全参构造方法 @AllArgsConstructor
 * 无参构造方法 @NoArgsConstructor
 * @JsonInclude(JsonInclude.Include.NON_NULL)
 * 将使得类中所有的属性都使用此配置，作用：此注解设置为包含非空时，就会包含非空的配置。
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JsonResult<T> {
    /**
     * 状态码
     */
    private Integer state;

    /**
     * 描述信息
     */
    private String message;

    /**
     * 返回给客户端的具体数据，因不应返回的数据类型是什么，所以使用Object类型进行存放
     */
    private T data;

    /**
     * 作用：调用时返回JsonResult对象，对象中的状态码设置为1，代表成功
     * 意义：当请求成功时，我们不需要考虑给前端发送提示信息，这时我们只需要给前端响应一个代表着请求成功的状态码就可以了。
     * 为什么这样写？：当请求状态成功时，首先，因为此方法是静态方法，可以直接调用此方法，获取封装好的属性JsonResult对象
     * @return
     */
    public static JsonResult<Void> ok(){
        //此处我们可以用代码少的方法调用代码多的方法，来提高代码的复用性
       return ok(null);
    }

    /**
     * ok方法的重载方法，此方法会接收一个object类型的参数，此参数为controller调用service层获取到的想要给浏览器发送的数据
     * @param data
     * @return
     */
    public static<T> JsonResult<T> ok(T data){
        JsonResult jr = new JsonResult();
        jr.setState(ServiceCode.OK.getValue());
        jr.setData(data);
        return jr;
    }

    /**
     * 出现异常时调用此方法
     * 作用：当此方法被调用时，可以返回一个JsonResult对象，此对象中保存着调用时传递过来的状态码和描述信息
     * @param state 状态码
     * @param message 描述信息
     * @return
     */
    public static JsonResult<Void> fail(ServiceCode state,String message){
        JsonResult jr = new JsonResult();
        jr.setState(state.getValue());
        jr.setMessage(message);
        return jr;
    }

    /**
     * fail的重载方法，可以将异常直接转换为JsonResult对象并返回,可以让调用者更加灵活的调用。
     * @param e
     * @return
     */
    public static JsonResult<Void> fail(ServiceException e){
        return fail(e.getServiceCode(),e.getMessage());
    }

}
